<template>
  <div>
    data.x: {{ data.x }}
    <button @click="click1">+1</button>

    <!--data.a.x {{data.a.x}}
    <button @click="click2">+1</button>-->

    data.a.x.count {{data.a.x.count}}
    <button @click="click3">+1</button>

    data.y {{data.y}}
    <button @click="click4">+1</button>
  </div>
</template>

<script>
import { ref, reactive } from "@vue/composition-api";

export default {
  setup() {
    const data = reactive({
      a:{}
    });

    /** 这里直接给data上不存在的x属性赋值,是能够赋值的
     * 但这个属性不是响应式的,会影响第一次渲染,但后面再次改变这个属性的值时,则不会触发视图更新*/
    data.x = 0;

    /** ↓这样改变data.x,每次都会进入 console.log(1) 的判断体内,即data.x的值不会被改变*/
    /*setInterval(() => {
      console.log("setInterval");
      if (!data.x) {
        console.log(1);
        data.x = 0;
      } else {
        console.log(2);
        data.x = data.x + 1;
      }
      console.log(data)
    }, 1000);*/

    /** ↓这种方式点击会导致data.x的值发生改变,但也不会触发更新*/
    const click1 = () => {
      console.log("click1");
      console.log("data.x:", data.x); // 你会发现每次点击这个data.x的确变了值,但不触发视图更新
      data.x = data.x + 1;
    };

    /** ↓即使不是root $data(一级属性),也是一样的*/
    // data.a.x = 0;
    /*const click2 = () => {
      console.log("click2");
      console.log("data.a.x:", data.a.x); // 你会发现每次点击这个data.x的确变了值,但不触发视图更新
      data.a.x = data.a.x + 1;
    };*/

    /** ↓即使赋的值不是一个普通类型的值而是一个对象,也不是响应式*/
    data.a.x = {count:1};
    const click3 = () => {
      console.log("click3");
      console.log("data.a.x:", data.a.x); // 你会发现每次点击这个data.x的确变了值,但不触发视图更新
      data.a.x.count = data.a.x.count + 1;
    };

    data.y = {count:1};
    const click4 = () => {
      console.log("click4");
      console.log("data.y:", data.y);
      data.y.count = data.y.count + 1;
    };

    /** 而如果不是reactive而是采用ref*/
    const data2 = ref({});
    /** 直接会报错:
     * [Vue warn]: Error in data(): "TypeError: Cannot add property x, object is not extensible"*/
    // data.x = 0;

    /** 结论: 和vue2.x一样,也无法直接让之前没有声明过的数据变成响应式的*/

    return {
      data,
      click1,
      // click2,
      click3,
      click4
    };
  }
};
</script>

<style scoped></style>
